package cn.maihe.elg.operation.centers.quanzhou.handler;

import cn.maihe.elg.operation.centers.quanzhou.dto.handler.*;
import cn.maihe.elg.operation.centers.quanzhou.enums.QuanzhouRespCodeEnum;
import cn.maihe.elg.operation.centers.quanzhou.exception.QuanzhouException;
import cn.maihe.elg.operation.centers.epoint.handler.EpointCenterTradeService;
import cn.maihe.elg.operation.centers.supports.annotation.CenterTradeService;
import cn.maihe.elg.operation.model.enums.CenterNoEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
 * @Description 泉州中心Handler处理器
 * @Author xxx
 * @Date 2025/08/31
 */
@Slf4j
@RestController
@RequestMapping("/v1/center")
public class QuanzhouCenterHandler {

    private final Map<String, EpointCenterTradeService> tradeServiceMap = new HashMap<>();

    public QuanzhouCenterHandler(@SuppressWarnings("rawtypes") final Collection<EpointCenterTradeService> baseCenterServices) {
        super();
        baseCenterServices.forEach(item -> {
            CenterTradeService annotation = AnnotationUtils.findAnnotation(item.getClass(), CenterTradeService.class);
            if (annotation != null) {
                String tradeService = annotation.tradeType().name().toLowerCase();
                this.tradeServiceMap.put(tradeService, item);
                log.info("注册泉州中心交易服务: {}", tradeService);
            }
        });
    }

    /**
     * 投保申请接口
     * @param centerNo 中心编号
     * @param orgCode 机构代码
     * @param tradeType 交易类型
     * @param reqDTO 请求参数
     * @return 响应结果
     */
    @PostMapping("/{centerNo}/{orgCode}/bh/{tradeType}")
    public QuanzhouApplyRespDTO apply(
            @PathVariable String centerNo,
            @PathVariable String orgCode,
            @PathVariable String tradeType,
            @Valid @RequestBody QuanzhouApplyReqDTO reqDTO) {

        log.info("泉州中心投保申请接口调用，centerNo: {}, orgCode: {}, tradeType: {}", centerNo, orgCode, tradeType);

        try {
            // 验证中心编号
            validateCenterNo(centerNo);

            // 验证交易类型
            if (!"apply".equals(tradeType)) {
                throw new QuanzhouException(QuanzhouRespCodeEnum.PARAM_ERROR, "交易类型错误");
            }

            // 业务逻辑由@CenterTradeService注解的service类自动处理
            return doService("baohanapply", reqDTO, QuanzhouApplyRespDTO.class);

        } catch (QuanzhouException e) {
            log.error("泉州中心投保申请失败: {}", e.getMessage());
            return QuanzhouApplyRespDTO.failure(e.getStatus().getMessage());
        } catch (Exception e) {
            log.error("泉州中心投保申请异常: {}", e.getMessage(), e);
            return QuanzhouApplyRespDTO.failure("系统异常");
        }
    }

    /**
     * 退保申请接口
     */
    @PostMapping("/{centerNo}/{orgCode}/bh/surrender")
    public QuanzhouSurrenderRespDTO surrender(
            @PathVariable String centerNo,
            @PathVariable String orgCode,
            @Valid @RequestBody QuanzhouSurrenderReqDTO reqDTO) {

        log.info("泉州中心退保申请接口调用，centerNo: {}, orgCode: {}", centerNo, orgCode);

        try {
            validateCenterNo(centerNo);
            // 业务逻辑由@CenterTradeService注解的service类自动处理
            return doService("baohansurrender", reqDTO, QuanzhouSurrenderRespDTO.class);

        } catch (QuanzhouException e) {
            log.error("泉州中心退保申请失败: {}", e.getMessage());
            return QuanzhouSurrenderRespDTO.failure(e.getStatus().getMessage());
        } catch (Exception e) {
            log.error("泉州中心退保申请异常: {}", e.getMessage(), e);
            return QuanzhouSurrenderRespDTO.failure("系统异常");
        }
    }

    /**
     * 申请关闭接口
     */
    @PostMapping("/{centerNo}/{orgCode}/bh/close")
    public QuanzhouCloseRespDTO close(
            @PathVariable String centerNo,
            @PathVariable String orgCode,
            @Valid @RequestBody QuanzhouCloseReqDTO reqDTO) {

        log.info("泉州中心申请关闭接口调用，centerNo: {}, orgCode: {}", centerNo, orgCode);

        try {
            validateCenterNo(centerNo);
            // 业务逻辑由@CenterTradeService注解的service类自动处理
            return doService("baohanclose", reqDTO, QuanzhouCloseRespDTO.class);

        } catch (QuanzhouException e) {
            log.error("泉州中心申请关闭失败: {}", e.getMessage());
            return QuanzhouCloseRespDTO.failure(e.getStatus().getMessage());
        } catch (Exception e) {
            log.error("泉州中心申请关闭异常: {}", e.getMessage(), e);
            return QuanzhouCloseRespDTO.failure("系统异常");
        }
    }

    /**
     * 理赔申请接口
     */
    @PostMapping("/{centerNo}/{orgCode}/bh/claim")
    public QuanzhouClaimRespDTO claim(
            @PathVariable String centerNo,
            @PathVariable String orgCode,
            @Valid @RequestBody QuanzhouClaimReqDTO reqDTO) {

        log.info("泉州中心理赔申请接口调用，centerNo: {}, orgCode: {}", centerNo, orgCode);

        try {
            validateCenterNo(centerNo);
            // 业务逻辑由@CenterTradeService注解的service类自动处理
            return doService("baohanclaim", reqDTO, QuanzhouClaimRespDTO.class);

        } catch (QuanzhouException e) {
            log.error("泉州中心理赔申请失败: {}", e.getMessage());
            return QuanzhouClaimRespDTO.failure(e.getStatus().getMessage());
        } catch (Exception e) {
            log.error("泉州中心理赔申请异常: {}", e.getMessage(), e);
            return QuanzhouClaimRespDTO.failure("系统异常");
        }
    }

    /**
     * 执行service调用的通用方法
     */
    private <T> T doService(String tradeType, Object reqDTO, Class<T> respClass) {
        String serviceKey = tradeType.toLowerCase();

        if (!this.tradeServiceMap.containsKey(serviceKey)) {
            log.error("不支持的交易类型: {}", tradeType);
            throw new QuanzhouException(QuanzhouRespCodeEnum.PARAM_ERROR, "不支持的交易类型");
        }

        try {
            EpointCenterTradeService service = this.tradeServiceMap.get(serviceKey);
            // 由于QuanzhouCenterHandler使用的是特定的DTO类型，需要进行适配
            Object result = service.doService(CenterNoEnum.EPOINT_QUANZHOU, "default", new HashMap<>(), new HashMap<>());
            return respClass.cast(result);
        } catch (Exception e) {
            log.error("服务调用失败: {}", e.getMessage(), e);
            throw new QuanzhouException(QuanzhouRespCodeEnum.SYSTEM_ERROR, "服务调用失败: " + e.getMessage());
        }
    }

    /**
     * 验证中心编号
     */
    private void validateCenterNo(String centerNo) {
        // 验证是否为泉州中心编号
        if (!CenterNoEnum.EPOINT_QUANZHOU.getCenterNo().equals(centerNo) &&
                !CenterNoEnum.QUANZHOU.getCenterNo().equals(centerNo)) {
            throw new QuanzhouException(QuanzhouRespCodeEnum.PARAM_ERROR, "中心编号不匹配");
        }
    }
}